/*
 * Created by SharpDevelop.
 * User: daniel
 * Date: 12/26/2006
 * Time: 11:49 AM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using Gtk;
using System;

namespace MonoDoku
{
	/// <summary>
	/// Description of Window1.
	/// </summary>
	public class Window1 : Window
	{
		Notebook notebook;
		Button solvebutton, solvebutton2, clearbutton, resetbutton;
		Entry[,] entries;
		Entry[,] entries2;
		Table table;
		int dimension;
		public Window1(int dimension) : base("MonoDoku " + Utility.version_number)
		{
			entries = new Entry[dimension,dimension];
			entries2 = new Entry[dimension,dimension];
			table = new Table( (uint) dimension + 1, (uint) dimension, true );
			this.dimension = dimension;
			
			for(int i = 0; i < Utility.grid_width( entries ); i++){
				for(int j = 0; j < Utility.grid_height( entries ); j++){
					entries[i,j] = new Entry(1);
					entries[i,j].WidthChars = 1;
					table.Attach( entries[i,j], (uint)i, (uint)i+1, (uint)j, (uint)j+1 );
				}
			}
			
			table.RowSpacing = 1;
			table.ColumnSpacing = 1;

			int[,] defaultGroups = Utility.default_groups( dimension );
			Table table2 = new Table( (uint) dimension + 1, (uint) dimension, true );
			for(int i = 0; i < Utility.grid_width( entries ); i++){
				for(int j = 0; j < Utility.grid_height( entries ); j++){
					entries2[i,j] = new Entry(1);
					entries2[i,j].WidthChars = 2;
					entries2[i,j].Text = defaultGroups[i,j] + "";
					table2.Attach( entries2[i,j], (uint)i, (uint)i+1, (uint)j, (uint)j+1 );
				}
			}
			
			solvebutton = new Button( "Solve" );
			solvebutton.Clicked += solve;
			solvebutton2 = new Button( "Solve" );
			solvebutton2.Clicked += solve;
			table.Attach( solvebutton, (uint) dimension / 2, (uint) dimension, (uint) dimension, (uint) dimension + 1);
			table2.Attach( solvebutton2, (uint) dimension / 2, (uint) dimension, (uint) dimension, (uint) dimension + 1);

			clearbutton = new Button( "Clear" );
			clearbutton.Clicked += clear_puzzle;
			table.Attach( clearbutton, 0, (uint) dimension / 2, (uint) dimension, (uint) dimension +1);
			
			resetbutton = new Button( "Reset" );
			resetbutton.Clicked += reset_groups;
			table2.Attach( resetbutton, 0, (uint) dimension / 2, (uint) dimension, (uint) dimension +1);

			table2.RowSpacing = 1;
			table2.ColumnSpacing = 1;
			
			notebook = new Notebook();
			
			notebook.AppendPage( table, new Label("Grid") );
			notebook.AppendPage( table2, new Label("Groups") );
			Add( notebook );
			ShowAll();
			SetDefaultSize( 600,600 );
			DeleteEvent += OnDelete;

			
			
		}
		
		public static void init_gui(int dimension){

			Application.Init ();
			Window window = new Window1( dimension );
			Application.Run ();

		}
		
		
		static void OnDelete (object o, DeleteEventArgs e)
		{
			Application.Quit ();
		}
		
		void solve( object o, EventArgs args ){
			Solver s = new Solver();
			Board board = s.solve( new Board( get_places(), get_groups() ) );
			
			if( o == solvebutton2 ) notebook.CurrentPage = 0;
			
			if( board == null ){
				MessageDialog md = new MessageDialog( this, DialogFlags.Modal, MessageType.Error, ButtonsType.Close, false, "Puzzle has no legal solution" );
				md.Run();
				md.Destroy();
			}else output_board( board );
			
			
		}
		
		private int[,] get_places(){
			int[,] toReturn = new int[dimension,dimension];
			for(int i = 0; i < dimension; i++ ){
				for(int j = 0; j < dimension; j++ ){
					if( entries[i,j].Text == "" ) toReturn[i,j] = 0;
					else toReturn[i,j] = int.Parse( entries[i,j].Text );
				}
			}
			return toReturn;
		}
		
		private void output_board( Board board ){
			for(int i = 0; i < Utility.grid_width( entries ); i++){
				for(int j = 0; j < Utility.grid_height( entries ); j++){
					entries[i,j].Text = "" + board.get_board()[i,j];
				}
			}
		}
		
		private int[,] get_groups(){
			int[,] toReturn = new int[dimension,dimension];
			for(int i = 0; i < dimension; i++ ){
				for(int j = 0; j < dimension; j++ ){
					toReturn[i,j] = int.Parse( entries2[i,j].Text );
				}
			}
			return toReturn;
		}
		
		private void reset_groups(object o, EventArgs e){
			int[,] groups = Utility.default_groups( dimension );
			
			for( int i = 0; i < Utility.grid_width( groups ); i++){
				for( int j = 0; j < Utility.grid_height( groups); j++){
					entries2[i,j].Text = groups[i,j] + "";
				}
			}
		}
		
		private void clear_puzzle(object o, EventArgs e){
			foreach( Entry entry in entries ){
				entry.Text = "";
			}
		}
		
	}
}
